package cn.explink.dop.service.impl;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import cn.explink.distributor.framework.CommonCondition;
import cn.explink.distributor.framework.Condition;
import cn.explink.distributor.framework.Order;
import cn.explink.distributor.framework.OrderCluster;
import cn.explink.distributor.framework.Target;
import cn.explink.distributor.framework.exception.NoneTargetFoundException;
import cn.explink.dop.dao.AreaDao;
import cn.explink.dop.dao.DeliveryManDao;
import cn.explink.dop.dao.DistributeStrategyDao;
import cn.explink.dop.dao.OrderDao;
import cn.explink.dop.distributor.FoodDistributor;
import cn.explink.dop.distributor.condition.DeliveryArea;
import cn.explink.dop.distributor.condition.DeliveryDistance;
import cn.explink.dop.distributor.condition.HavingDeliveryMan;
import cn.explink.dop.distributor.condition.HavingPOS;
import cn.explink.dop.distributor.condition.HavingWarmBox;
import cn.explink.dop.distributor.condition.RefuseDeliveryMan;
import cn.explink.dop.entity.vo.AreaVO;
import cn.explink.dop.entity.vo.ConditionVO;
import cn.explink.dop.entity.vo.DeliveryManVO;
import cn.explink.dop.entity.vo.DistributeStrategyVO;
import cn.explink.dop.entity.vo.OrderVO;
import cn.explink.dop.entity.vo.StorefrontVO;
import cn.explink.dop.enums.DeliveryManStatusEnum;
import cn.explink.dop.enums.OrderPayMethodEnum;
import cn.explink.dop.enums.OrderStatusEnum;
import cn.explink.dop.enums.pub.YesNoEnum;
import cn.explink.dop.gis.Center;
import cn.explink.dop.gis.Cluster;
import cn.explink.dop.gis.ClusterUtil;
import cn.explink.dop.gis.Point;
import cn.explink.dop.service.PushMessageService;
import cn.explink.dop.service.SmartDistributorService;
import cn.explink.dop.tools.GetHttpConnect;
import cn.explink.dop.tools.GetProjectUrl;
import cn.explink.dop.tools.Params;
import cn.explink.dop.tools.PushNewMessageRunnable;
import cn.explink.eap.core.util.DataUtils;
import cn.explink.eap.core.util.JSONHelper;

@Service("smartDistributorService")
public class SmartDistributorServiceImpl implements SmartDistributorService {

	private static Logger logger = LoggerFactory
			.getLogger(SmartDistributorServiceImpl.class);

	/**
	 * 分组的直径（单位：米）
	 *
	 */
	private static final int GROUP_DIAMETER = 1000;

	/**
	 * 分单提前的小时数
	 */
	@SuppressWarnings("unused")
	private static final int DISTRIBUTE_EARLY_TIME = 1;

	@Autowired
	private OrderDao orderDao;

	@Autowired
	private DeliveryManDao deliveryManDao;

	@Autowired
	private DistributeStrategyDao distributeStrategyDao;

	@Autowired
	private AreaDao areaDao;

	@Autowired
	private PushMessageService pushMessageService;

	@Override
	public void work() {
		// 1、获取所有未分配订单信息(并且给这些订单上加上对比信息：每个订单可以让哪些配送的人员送)

		List<OrderVO> toAssignOrderVOList = this.getToAssignOrderList();
		SmartDistributorServiceImpl.logger.info("获取待分配订单成功！订单个数："
				+ toAssignOrderVOList.size());
		// 2、对订单按照客户地址进行分组
		List<Order> groupedOrderList = this.group(toAssignOrderVOList);
		if (SmartDistributorServiceImpl.logger.isDebugEnabled()) {
			this.printClusterInfo(groupedOrderList);
		}
		// 3、获取配送员信息
		// 并为过滤掉拒绝过某订单的配送员做准备（给配送人员加上对比信息：id）
		List<Target> targetList = this
				.getCanAcceptTargetList(toAssignOrderVOList);
		SmartDistributorServiceImpl.logger.info("获取可用的配送人员成功！");
		// 4、分单
		this.doDistribute(groupedOrderList, targetList);
	}

	private void doDistribute(List<Order> groupedOrderList,
			List<Target> targetList) {
		FoodDistributor foodDistributor = new FoodDistributor(targetList);
		SmartDistributorServiceImpl.logger.info("开始分配！");
		for (Order groupedOrder : groupedOrderList) {
			/**
			 * 1、检查订单里面是否有过期的订单,如果订单过期，则把状态改变，给配送员发送信息，取消配送，并且将它从待分配订单列表里去掉
			 * 2、分单之前，对比订单的被拒配送员列表和可用配送员列表--该订单门店的全部派送员（超时未接的配送员也默认为拒绝了该订单，
			 * 只是还没有持久化到数据库，
			 * 但是订单的被拒列表中已经又该配送员）,如果该订单被所有配送员拒接了，那么清空refuse_deliveryman字段，
			 * 奖励金额加2,下次自动分配时自动分配（由于refuse_deliveryman被清空，所以下次会分配）
			 * while(it.hasNext()) { Object ele = it.next(); it.remove(); }
			 */
			OrderCluster oc = (OrderCluster) groupedOrder;
			// 1、检查订单里面是否有过期的订单,如果订单过期，则把状态改变，给配送员发送信息，取消配送，并且将它从待分配订单列表里去掉
			Iterator<Order> it = oc.getOrderList().iterator();
			while (it.hasNext()) {
				Order order = it.next();
				OrderVO ord = (OrderVO) order;
				if (ord.getAskSendTime() != null
						&& compareDate(new Date(), ord.getAskSendTime())) {
					SmartDistributorServiceImpl.logger.info("code:"
							+ ord.getCode() + ",订单已过期！");
					PushNewMessageRunnable pushmessage = new PushNewMessageRunnable(ord,null,2);
					Thread thread = new Thread(pushmessage);
					thread.start();

					ord.setStatus(OrderStatusEnum.OVERDUE.getValue());
					ord.setStatusChangeTime(new Date());
					ord.setUpdateDate(new Date());
					ord.setStatusLog(ord.getStatusLog()
							+ " 订单过期  时间:"
							+ DataUtils.date2Str(DataUtils.datetimeFormat));
					this.orderDao.saveOrUpdate(ord);
					it.remove();
				}

				RefuseDeliveryMan refuseDeliveryMan = new RefuseDeliveryMan();
				HavingDeliveryMan havingDeliveryMan = new HavingDeliveryMan();
				for (Condition condition : order.getConditionList()) {
					if (condition instanceof RefuseDeliveryMan) {
						refuseDeliveryMan = (RefuseDeliveryMan) condition;
					}
					if (condition instanceof HavingDeliveryMan) {
						havingDeliveryMan = (HavingDeliveryMan) condition;
					}
				}
				// 2、分单之前，对比订单的被拒配送员列表和可用配送员列表
				if (refuseDeliveryMan != null && havingDeliveryMan != null
						&& refuseDeliveryMan.isEqual(havingDeliveryMan)) {
					SmartDistributorServiceImpl.logger.info("code:"
							+ ord.getCode() + ",订单已被所有配送员拒绝，清空被拒字段！");
					OrderVO ordervo = (OrderVO) order;
					String refuseDeliveryman = new String();
					ordervo.setRefuseDeliveryman(refuseDeliveryman);
					ordervo.setStatus(OrderStatusEnum.NOT_ASSIGN.getValue()); // 把订单的状态置为未分配，把它当做一个新单子，从而所有配送员都可以再次被分配到
					if (ordervo.getRewardprice() < (Params.allRefuseReward + Params.orvertimeReward)) {
						ordervo.setRewardprice(ordervo.getRewardprice()
								+ Params.allRefuseReward);
					}
					for (Condition temp : ordervo.getConditionList()) {
						if (temp instanceof RefuseDeliveryMan) { // 情况当前该订单中的拒绝人员信息，让他能够参与分配
							List<String> List = new ArrayList<String>();
							((RefuseDeliveryMan) temp)
									.setRefusedeleveryManIdList(List);
							;
						}
					}
					// 给该配送员推送消息，告知其已被超时未接该订单，默认其拒绝该订单的配送
					PushNewMessageRunnable pushmessage = new PushNewMessageRunnable(ordervo,null,2);
					Thread thread = new Thread(pushmessage);
					thread.start();

				}
			}

			// 分单

			try {
				SmartDistributorServiceImpl.logger.info("订单组开始分配！");
				foodDistributor.initTargetList();
				List<Target> foundTargetList = new ArrayList<Target>();
				foundTargetList = foodDistributor
						.distribute(groupedOrder, true);
				DeliveryManVO deliveryManVO = (DeliveryManVO) foundTargetList
						.get(0);
				List<Order> orderList = ((OrderCluster) groupedOrder)
						.getOrderList();
				for (Order order : orderList) {
					OrderVO orderVO = (OrderVO) order;
					/**
					 * 如果是已分配的订单被再次分配，那么就是分配后配送员超时未接的订单，
					 * 这种情况默认该配送员拒接订单,并且前配送员要填进refuse_deliveryan中。
					 * 如果该订单入库时间已经超过了奖励时间，那么另加奖励
					 * 
					 */
					if (orderVO.getStatus() == OrderStatusEnum.ASSIGNED
							.getValue()) {
						/**
						 * 取出订单的入库时间，如果该时间已经超多了奖励时间，那么就在原奖励上加上金额
						 */
						SimpleDateFormat d = new SimpleDateFormat(
								"yyyy-MM-dd HH:mm:ss");// 格式化时间
						String nowtime = d.format(new Date());// 按以上格式
																// 将当前时间转换成字符串
						String creatTime = d.format(orderVO.getCreateDate());
						long result = 0;
						try {
							result = (d.parse(nowtime).getTime() - d.parse(
									creatTime).getTime()) / 60000;
						} catch (ParseException e) {
							SmartDistributorServiceImpl.logger.info(e
									.getMessage());
						}
						if (orderVO.getRewardprice() < (Params.allRefuseReward + Params.orvertimeReward)) {
							if (result > Params.orverTime) {
								orderVO.setRewardprice(orderVO.getRewardprice()
										+ Params.orvertimeReward);
							}
						}

						/**
						 * 超时未接的配送员默认是拒接订单，所以将其放入拒收配送员字段
						 */
						if (StringUtils.isBlank(orderVO.getRefuseDeliveryman())) {
							orderVO.setRefuseDeliveryman(orderVO
									.getDeliveryManID());
						} else {
							orderVO.setRefuseDeliveryman(orderVO
									.getRefuseDeliveryman()
									+ ","
									+ orderVO.getDeliveryManID());
						}
						// 给该配送员推送消息，告知其已被超时未接该订单，默认其拒绝该订单的配送
						PushNewMessageRunnable pushmessage = new PushNewMessageRunnable(orderVO,null,2);
						Thread thread = new Thread(pushmessage);
						thread.start();
					}
					// 设置订单与配送员关联关系
					orderVO.setDeliveryMan(deliveryManVO);
					// 状态改为“已分配待确认”
					orderVO.setStatus(OrderStatusEnum.ASSIGNED.getValue());
					orderVO.setStatusChangeTime(new Date());
					orderVO.setDistributeTime(new Date());
					orderVO.setUpdateDate(new Date());
					if (StringUtils.isNotBlank(orderVO.getDeliveryManID())) {
						orderVO.setPostmanId(orderVO.getDeliveryMan()
								.getPostmanid());
						orderVO.setDeliveryManPhone(orderVO.getDeliveryMan()
								.getDelTelephone());
					}
					orderVO.setDeliveryManName(deliveryManVO.getDelName());
					orderVO.setStatusLog(orderVO.getStatusLog()
							+ " 分单方式：智能分单  分单时间:"
							+ DataUtils.date2Str(DataUtils.datetimeFormat)
							+ " 状态：" + OrderStatusEnum.ASSIGNED.getText());				
					this.orderDao.saveOrUpdate(orderVO);				
					/**
					 * 保存成功后，给快递员推送通知
					 * 请求接口如:http://api.neolix.cn/open/push/new_order
					 * ?token=ac5f97115cd4df280e37871c7569d862
					 * &sign=NEW_ORDER_O2O&postman_id=41&out_trade_no=1375
					 */
					PushNewMessageRunnable pushmessage = new PushNewMessageRunnable(orderVO,deliveryManVO,1);
					Thread thread = new Thread(pushmessage);
					thread.start();										
				}
			} catch (NoneTargetFoundException e) {
				// 订单组没有找到合适的分单对象，启用按单分配
				SmartDistributorServiceImpl.logger.error("订单组分配失败，单个订单开始分配！");
				List<Target> foundTargetList = new ArrayList<Target>();
				if (groupedOrder instanceof OrderCluster) {
					OrderCluster ordercluster = (OrderCluster) groupedOrder;
					for (Order order : ordercluster.getOrderList()) {
						try {
							foodDistributor.initTargetList();
							foundTargetList = foodDistributor.distribute(order,
									true);
							DeliveryManVO deliveryManVO = (DeliveryManVO) foundTargetList
									.get(0);

							OrderVO orderVO = (OrderVO) order;
							/**
							 * 如果是已分配的订单被再次分配，那么就是分配后配送员超时未接的订单，
							 * 这种情况默认该配送员拒接订单,并且前配送员要填进refuse_deliveryan中。
							 * 如果该订单入库时间已经超过了奖励时间，那么另加奖励
							 * 
							 */
							if (orderVO.getStatus() == OrderStatusEnum.ASSIGNED
									.getValue()) {
								/**
								 * 取出订单的入库时间，如果该时间已经超多了奖励时间，那么就在原奖励上加上金额
								 */
								SimpleDateFormat d = new SimpleDateFormat(
										"yyyy-MM-dd HH:mm:ss");// 格式化时间
								String nowtime = d.format(new Date());// 按以上格式
																		// 将当前时间转换成字符串
								String creatTime = d.format(orderVO
										.getCreateDate());
								long result = 0;
								try {
									result = (d.parse(nowtime).getTime() - d
											.parse(creatTime).getTime()) / 60000;
								} catch (ParseException er) {
									SmartDistributorServiceImpl.logger.info(er
											.getMessage());
								}
								if (orderVO.getRewardprice() < (Params.allRefuseReward + Params.orvertimeReward)) {
									if (result > Params.orverTime) {
										orderVO.setRewardprice(orderVO
												.getRewardprice()
												+ Params.orvertimeReward);
									}
								}

								/**
								 * 超时未接的配送员默认是拒接订单，所以将其放入拒收配送员字段
								 */
								if (StringUtils.isBlank(orderVO
										.getRefuseDeliveryman())) {
									orderVO.setRefuseDeliveryman(orderVO
											.getDeliveryManID());
								} else {
									orderVO.setRefuseDeliveryman(orderVO
											.getRefuseDeliveryman()
											+ ","
											+ orderVO.getDeliveryManID());
								}
								// 给该配送员推送消息，告知其已被超时未接该订单，默认其拒绝该订单的配送
								PushNewMessageRunnable pushmessage = new PushNewMessageRunnable(orderVO,null,2);
								Thread thread = new Thread(pushmessage);
								thread.start();	
							}
							// 设置订单与配送员关联关系
							orderVO.setDeliveryMan(deliveryManVO);
							// 状态改为“已分配待确认”
							orderVO.setStatus(OrderStatusEnum.ASSIGNED
									.getValue());
							orderVO.setStatusChangeTime(new Date());
							orderVO.setDistributeTime(new Date());
							orderVO.setUpdateDate(new Date());
							if (StringUtils.isNotBlank(orderVO
									.getDeliveryManID())) {
								orderVO.setPostmanId(orderVO.getDeliveryMan()
										.getPostmanid());
								orderVO.setDeliveryManPhone(orderVO
										.getDeliveryMan().getDelTelephone());
							}
							orderVO.setDeliveryManName(deliveryManVO
									.getDelName());
							orderVO.setStatusLog(orderVO.getStatusLog()
									+ " 分单方式：智能分单  分单时间:"
									+ DataUtils
											.date2Str(DataUtils.datetimeFormat)
									+ " 状态："
									+ OrderStatusEnum.ASSIGNED.getText());							
							this.orderDao.saveOrUpdate(orderVO);
							/**
							 * 保存成功后，给快递员推送通知
							 * 请求接口如:http://api.neolix.cn/open/push
							 * /new_order?token
							 * =ac5f97115cd4df280e37871c7569d862&
							 * sign=NEW_ORDER_O2O
							 * &postman_id=41&out_trade_no=1375
							 */
							PushNewMessageRunnable pushmessage = new PushNewMessageRunnable(orderVO,deliveryManVO,1);
							Thread thread = new Thread(pushmessage);
							thread.start();	
						} catch (NoneTargetFoundException err) {
							SmartDistributorServiceImpl.logger
									.error("单个订单分配失败！");
						}

					}
				}

			}
		}
	}
		
	private void printClusterInfo(List<Order> groupedOrderList) {
		for (Order groupedOrder : groupedOrderList) {
			StringBuffer sb = new StringBuffer();
			List<Order> orderList = ((OrderCluster) groupedOrder)
					.getOrderList();
			for (Order order : orderList) {
				OrderVO orderVO = (OrderVO) order;
				String custAddress = orderVO.getCustAddress();
				sb.append(custAddress + "/n");
			}
			SmartDistributorServiceImpl.logger.debug(sb.toString());
		}

	}

	/**
	 * 通过订单上的客户地址进行分组
	 *
	 * @param toAssignOrderVOList
	 * @return 分组后的订单
	 */
	private List<Order> group(List<OrderVO> toAssignOrderVOList) {
		List<Order> orderClusterList = new ArrayList<Order>();

		// 未分组的订单点（获取订单的地理位置信息）
		List<Point> notGroupedOrderPointList = new ArrayList<Point>();
		for (OrderVO orderVO : toAssignOrderVOList) {
			String custPosition = orderVO.getCustPosition();
			Point orderPoint = new Point(orderVO.getId(), new Point(
					custPosition).getLng(), new Point(custPosition).getLat());

			notGroupedOrderPointList.add(orderPoint);
		}
		// 根据位置信息，给这些订单分出自然组
		List<Cluster> clusterOfOrderList = ClusterUtil.cluster(
				notGroupedOrderPointList,
				SmartDistributorServiceImpl.GROUP_DIAMETER);

		for (Cluster clusterOfOrder : clusterOfOrderList) {
			List<Order> groupedOrderVOList = new ArrayList<Order>();
			Center center = clusterOfOrder.getCenter();
			List<Point> groupedPointList = clusterOfOrder.getPointList();
			for (Point groupedPoint : groupedPointList) {
				for (OrderVO toAssignOrderVO : toAssignOrderVOList) {
					if (groupedPoint.getId().equals(toAssignOrderVO.getId())) {
						groupedOrderVOList.add(toAssignOrderVO); // 得到在组内的点
					}
				}
			}

			OrderCluster orderCluster = new OrderCluster(center.getLng(),
					center.getLat(), groupedOrderVOList);
			List<Cluster> storefrontClusterList = this
					.groupByStorefrontCoordinate(orderCluster);// 对于每组的订单，按照门店坐标进行分组

			// 查询分单策略，得到策略规则
			DistributeStrategyVO distributeStrategyList = this.distributeStrategyDao
					.getEnableDistributeStrategyList();
			List<ConditionVO> conditionList = distributeStrategyList
					.getConditionList();

			List<OrderCluster> splittedOrderCluster = this.splitOrderCluster(
					orderCluster, storefrontClusterList, conditionList);// 对订单组进行拆分

			orderClusterList.addAll(splittedOrderCluster);
		}
		return orderClusterList;
	}

	/**
	 * 对订单组进行拆分
	 *
	 * @param orignOrderCluster
	 * @param storefrontClusterList
	 * @return
	 */
	private List<OrderCluster> splitOrderCluster(
			OrderCluster orignOrderCluster,
			List<Cluster> storefrontClusterList, List<ConditionVO> conditionList) {
		List<OrderCluster> splittedOrderClusterList = new ArrayList<OrderCluster>();
		List<Order> orignOrderList = orignOrderCluster.getOrderList();
		for (Cluster storefrontCluster : storefrontClusterList) {
			OrderCluster splittedOrderCluster = new OrderCluster(
					orignOrderCluster.getCenter());
			List<Order> orderList = new ArrayList<Order>();
			for (Order orginOrder : orignOrderList) {

				List<Point> storefrontPointList = storefrontCluster
						.getPointList();
				for (Point storefrontPoint : storefrontPointList) {
					if (((OrderVO) orginOrder).getId().equals(
							storefrontPoint.getId())) {
						orderList.add(orginOrder);
					}
				}
			}
			List<CommonCondition> commonConditionList = new ArrayList<CommonCondition>();
			for (ConditionVO condition : conditionList) {
				// 根据距离来分单
				if (condition instanceof DeliveryDistance) {
					DeliveryDistance deliveryDistance = (DeliveryDistance) condition;
					deliveryDistance.setStorefrontCoordinate(JSONHelper
							.bean2json(storefrontCluster.getCenter()));
					commonConditionList.add(deliveryDistance);
				}
				// 根据所在门店来分单
				if (condition instanceof HavingDeliveryMan) {
					HavingDeliveryMan havingDeliveryMan = (HavingDeliveryMan) condition;
					commonConditionList.add(havingDeliveryMan);
				}
			}
			// 得到分单策略的具体要求
			splittedOrderCluster.setConditionList(commonConditionList);
			splittedOrderCluster.setOrderList(orderList);// 保存订单的数据（包括对比数据）
			splittedOrderClusterList.add(splittedOrderCluster);// （订单的集合）
		}
		return splittedOrderClusterList;
	}

	/**
	 * 对于每组的订单，按照门店坐标进行分组
	 *
	 * @param orderCluster
	 * @return
	 */
	private List<Cluster> groupByStorefrontCoordinate(OrderCluster orderCluster) {
		// 未分组的店面点
		List<Point> notGroupedStorefrontPointList = new ArrayList<Point>();
		List<Order> orderList = orderCluster.getOrderList();
		for (Order order : orderList) {
			OrderVO orderVO = (OrderVO) order;
			String storefrontCoordinate = orderVO.getStorefrontCoordinate();
			Point storefrontPoint = new Point(orderVO.getId(), new Point(
					storefrontCoordinate).getLng(), new Point(
					storefrontCoordinate).getLat());
			notGroupedStorefrontPointList.add(storefrontPoint);
		}

		List<Cluster> clusterOfStorefrontList = ClusterUtil.cluster(
				notGroupedStorefrontPointList,
				SmartDistributorServiceImpl.GROUP_DIAMETER);
		Collections.sort(clusterOfStorefrontList);
		return clusterOfStorefrontList;
	}

	/**
	 * 获取可接单配送员
	 *
	 * @param orderVOList
	 * @return
	 */
	private List<Target> getCanAcceptTargetList(List<OrderVO> orderVOList) {
		List<Target> targetList = new ArrayList<Target>();
		List<DeliveryManVO> deliveryManVOList = this.deliveryManDao
				.getByStatus(DeliveryManStatusEnum.CAN_ACCEPT.getValue());
		for (DeliveryManVO deliveryManVO : deliveryManVOList) {
			DistributeStrategyVO distributeStrategyList = this.distributeStrategyDao
					.getEnableDistributeStrategyList();
			List<ConditionVO> conditionList = distributeStrategyList
					.getConditionList();
			for (ConditionVO condition : conditionList) {

				if (condition instanceof HavingDeliveryMan) {
					// 配送人员把id放到对比条件中，便于对比该派送员是否在该订单指定的门店里
					HavingDeliveryMan havingDeliveryMan = (HavingDeliveryMan) condition;
					List<String> havingDeliveryManList = new ArrayList<String>();
					havingDeliveryManList.add(deliveryManVO.getId());
					havingDeliveryMan
							.setDeleveryManIdList(havingDeliveryManList);
				}

				if (condition instanceof RefuseDeliveryMan) {
					// 将配送人员把id放到对比条件中，便于对比订单是否被拒绝过
					RefuseDeliveryMan refuseDeliveryMan = (RefuseDeliveryMan) condition;
					List<String> refuseDeliveryManList = new ArrayList<String>();
					refuseDeliveryManList.add(deliveryManVO.getId());
					refuseDeliveryMan
							.setRefusedeleveryManIdList(refuseDeliveryManList);
				}

				if (condition instanceof DeliveryArea) {
					// 对于配送区域 获取该配送员负责的配送区域ID
					DeliveryArea deliveryArea = (DeliveryArea) condition;
					List<String> areaIdList = new ArrayList<String>();
					for (AreaVO areaVO : deliveryManVO.getAreaList()) {
						areaIdList.add(areaVO.getId());
					}
					deliveryArea.setAreaIdList(areaIdList);
				}
				if (condition instanceof DeliveryDistance) {
					DeliveryDistance deliveryDistance = (DeliveryDistance) condition;
					deliveryDistance.setDeliverymanCoordinate(deliveryManVO
							.getCoordinate());
				}
				if (condition instanceof HavingPOS) {
					HavingPOS havingPOS = (HavingPOS) condition;
					if (YesNoEnum.YES.getValue() == deliveryManVO
							.getHavingPOS()) {
						havingPOS.setYesOrNo(true);
					} else {
						havingPOS.setYesOrNo(false);
					}
				}
				if (condition instanceof HavingWarmBox) {
					HavingWarmBox havingWarmBox = (HavingWarmBox) condition;
					if (YesNoEnum.YES.getValue() == deliveryManVO
							.getHavingWarmBox()) {
						havingWarmBox.setYesOrNo(true);
					} else {
						havingWarmBox.setYesOrNo(false);
					}
				}
			}
			List<CommonCondition> distributeAbilityList = new ArrayList<CommonCondition>();
			for (ConditionVO conditionVO : conditionList) {
				distributeAbilityList.add(conditionVO);
			}
			deliveryManVO.setDistributeAbilityList(distributeAbilityList);
			targetList.add(deliveryManVO);
		}
		return targetList;
	}

	/**
	 * 获取待分配订单列表并设置每个订单要求的分配条件
	 *
	 * @return
	 */
	private List<OrderVO> getToAssignOrderList() {
		List<OrderVO> orderVOList = this.getNotAssignOrder();
		for (OrderVO orderVO : orderVOList) {
			DistributeStrategyVO distributeStrategyList = this.distributeStrategyDao
					.getEnableDistributeStrategyList();
			List<ConditionVO> conditionList = new ArrayList<ConditionVO>();
			conditionList = distributeStrategyList.getConditionList();
			for (ConditionVO condition : conditionList) {

				if (condition instanceof HavingDeliveryMan) {
					// 将订单所对应门面的配送人员都放到对比条件中，便于之后对比
					HavingDeliveryMan havingDeliveryMan = (HavingDeliveryMan) condition;
					List<String> havingDeliveryManList = new ArrayList<String>();
					StorefrontVO storefrontVO = orderVO.getStorefrontEntity();
					for (DeliveryManVO temp : storefrontVO.getDeliveryManList()) {
						if (temp.getStatus() == 1) {
							havingDeliveryManList.add(temp.getId());
						}
					}
					havingDeliveryMan
							.setDeleveryManIdList(havingDeliveryManList);
				}

				if (condition instanceof RefuseDeliveryMan) {
					// 将曾经拒绝过该订单的配送人员放进属性中，便于对比订单是否被拒绝过
					RefuseDeliveryMan refuseDeliveryMan = (RefuseDeliveryMan) condition;
					List<String> refuseDeliveryManList = new ArrayList<String>();
					String[] refusedeliverymans = {};
					if (StringUtils.isNotBlank(orderVO.getRefuseDeliveryman())) {
						refusedeliverymans = orderVO.getRefuseDeliveryman()
								.split(",");
					}
					for (String temp : refusedeliverymans) {
						if (!StringUtils.isBlank(temp)) {
							refuseDeliveryManList.add(temp);
						}
					}
					/**
					 * 如果该订单属于已分配，但配送员超时未接，那么视为该配送员拒绝接货，这里先把该配送员填进拒绝人员对比条件
					 * 中（实际上refuse_deliveryman字段还未存
					 * ），然后在分配完成，保存该订单信息的时候再保存该配送员进refuse_deliveryman中
					 */
					if (orderVO.getStatus() == OrderStatusEnum.ASSIGNED
							.getValue()) {
						refuseDeliveryManList.add(orderVO.getDeliveryManID());
					}
					refuseDeliveryMan
							.setRefusedeleveryManIdList(refuseDeliveryManList);
				}

				if (condition instanceof DeliveryArea) {
					// 对于配送区域 设置订单地址落在的配送区域ID
					DeliveryArea deliveryArea = (DeliveryArea) condition;
					List<AreaVO> areaVOList = this.areaDao.getByAddress(orderVO
							.getCustAddress());
					List<String> areaIdList = new ArrayList<String>();
					for (AreaVO areaVO : areaVOList) {
						areaIdList.add(areaVO.getId());
					}
					deliveryArea.setAreaIdList(areaIdList);
				}
				if (condition instanceof DeliveryDistance) {
					DeliveryDistance deliveryDistance = (DeliveryDistance) condition;
					StorefrontVO storefrontEntity = orderVO
							.getStorefrontEntity();
					if (null != storefrontEntity) {
						deliveryDistance
								.setStorefrontCoordinate(storefrontEntity
										.getStoCoordinate());
					}

				}
				if (condition instanceof HavingPOS) {
					HavingPOS havingPOS = (HavingPOS) condition;
					if (OrderPayMethodEnum.POS_PAYMENT.getValue() == orderVO
							.getPayMethod()) {
						havingPOS.setYesOrNo(true);
					} else {
						havingPOS.setYesOrNo(false);
					}
				}
				if (condition instanceof HavingWarmBox) {
					HavingWarmBox havingWarmBox = (HavingWarmBox) condition;
					if (YesNoEnum.YES.getValue() == orderVO.getNeedWarmBox()) {
						havingWarmBox.setYesOrNo(true);
					} else {
						havingWarmBox.setYesOrNo(false);
					}
				}
			}
			List<CommonCondition> commonConditionList = new ArrayList<CommonCondition>();
			for (ConditionVO conditionVO : conditionList) {
				commonConditionList.add(conditionVO);
			}
			orderVO.setConditionList(commonConditionList);
		}
		return orderVOList;
	}

	/**
	 * 获取未分配订单
	 *
	 * @return
	 */
	private List<OrderVO> getNotAssignOrder() {
		List<Integer> statusList = new ArrayList<Integer>();
		statusList.add(OrderStatusEnum.NOT_ASSIGN.getValue());
		statusList.add(OrderStatusEnum.DISTRIBUTE_REFUSE.getValue());
		/*
		 * Date beginTime = DataUtils.getDate(); Date endTime =
		 * DateUtils.addHours(beginTime,
		 * SmartDistributorServiceImpl.DISTRIBUTE_EARLY_TIME); List<OrderVO>
		 * orderVOList = this.orderDao.getByStatusAndAskSendTime(statusList,
		 * null, null);//7.8注释
		 */

		List<OrderVO> orderVOList = this.orderDao
				.getOrderByStatusAndDistributiontime(statusList,
						OrderStatusEnum.ASSIGNED.getValue(),
						Params.redistributionTime);
		// List<OrderVO> orderVOList =
		// this.orderDao.getByStatusAndAskSendTime(statusList, beginTime,
		// endTime);
		return orderVOList;
	}

	/**
	 * 比较两个日期之间的大小
	 * 
	 * @param d1
	 * @param d2he
	 * @return 前者大于后者返回true 反之false
	 */
	public boolean compareDate(Date d1, Date d2) {
		Calendar c1 = Calendar.getInstance();
		Calendar c2 = Calendar.getInstance();
		c1.setTime(d1);
		c2.setTime(d2);

		int result = c1.compareTo(c2);
		if (result >= 0)
			return true;
		else
			return false;
	}
}
